package com.glp.work.flow.workflow.command;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.runtime.Execution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 节点跳转
 *
 * @author pengjia
 * @version 2020年6月5日 上午8:50:49
 */
@Component
@Slf4j
public class CommonJumpTaskCmd implements Command<Void> {

    private String procInstanceId;
    private String executionId;
    private String targetActivityId;
    private static RuntimeService runtimeService;

    public CommonJumpTaskCmd() {
    }

    public CommonJumpTaskCmd(String procInstanceId, String executionId, String targetActivityId) {
        this.procInstanceId = procInstanceId;
        this.targetActivityId = targetActivityId;
        this.executionId = executionId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        log.info("驳回到配置节点。processId={}，当前正执行的任务 executionId={}，目标节点 targetActivityId={}。", procInstanceId, executionId, this.targetActivityId);
        List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(procInstanceId).list();
        log.info("过滤前执行IDs：{}", executions);
        if (CollectionUtils.isNotEmpty(executions)) {
            executions = executions.stream().filter(predicate -> {
                if (predicate instanceof ExecutionEntityImpl) {
                    if (((ExecutionEntityImpl) predicate).isProcessInstanceType()) {
                        return false;
                    } else {
                        if (((ExecutionEntityImpl) predicate).isScope()) {
                            return false;
                        } else if (((ExecutionEntityImpl) predicate).isMultiInstanceRoot()) {
                            return false;
                        } else {
                            if (((ExecutionEntityImpl) predicate).isActive()) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    }
                }
                return false;
            }).collect(Collectors.toList());
            List<String> executionIds = executions.stream().map(Execution::getId).collect(Collectors.toList());
            runtimeService.createChangeActivityStateBuilder().processInstanceId(this.procInstanceId)
                    .moveExecutionsToSingleActivityId(executionIds, targetActivityId).changeState();
        }
        return null;
    }

    @Autowired
    public void setRuntimeService(RuntimeService runtimeService) {
        CommonJumpTaskCmd.runtimeService = runtimeService;
    }

}
